package minishell.object.format;

import java.io.File;
import java.text.DateFormat;
import java.util.Date;
import java.util.Formatter;

import org.lex.io.IO;

import minishell.object.IObject;

public abstract class FileFormatter implements ObjectFormatter
{
	public static enum Format { NAME, PATH, LONG };
	
	private static Format DEFAULT_FORMAT = Format.PATH;
	private static DateFormat timeFormatter = DateFormat.getTimeInstance(
		DateFormat.MEDIUM );
	private static DateFormat dateFormatter = DateFormat.getDateInstance( 
		DateFormat.MEDIUM );
	
	public static FileFormatter newFormatter( Format format )
	{
		switch( format )
		{
		case NAME:
			return new FileFormatter(){
				protected String formatFile( File file )
				{
					return file.getName();
				}
			};
		case PATH:
			return new FileFormatter(){
				protected String formatFile( File file )
				{
					return IO.getCanonicalPath( file );
				}
			};
		case LONG:
			return new FileFormatter(){
				StringBuilder buffer = new StringBuilder();
				Date date = new Date();
				protected String formatFile( File file )
				{
					buffer.setLength( 0 );
					// directory
					this.setAttribute( file.isDirectory(), 'd' );
					// readable
					this.setAttribute( file.canRead(), 'r' );
					// writable
					this.setAttribute( file.canWrite(), 'w' );
					// executable
					this.setAttribute( file.canExecute(), 'x' );					
					// date
					this.buffer.append( ' ' );
					Formatter f = new Formatter( buffer );
					this.date.setTime( file.lastModified() );
					f.format( "%10s", dateFormatter.format( date ) );
					// time
					this.buffer.append( ' ' );
					f.format( "%8s", timeFormatter.format( date ) );
					// size
					this.buffer.append( ' ' );
					f.format( "%12d", file.length() );
					// name
					this.buffer.append( ' ' );
					buffer.append( file.getName() );
					return buffer.toString();
				}
				
				private void setAttribute( boolean flag, char ch )
				{
					if( true == flag )
						buffer.append( ch );
					else
						buffer.append( '-' );
				}
			};
		default:
			return FileFormatter.newFormatter( FileFormatter.DEFAULT_FORMAT );
		}
	}
	
	public String format( IObject o )
	{
		Object value = o.getPrimitive();
		if( value instanceof File )
			return this.formatFile( (File) value );
		return o.toString();
	}
	
	protected abstract String formatFile( File file );
}
